﻿using Core.DataAccess.Model.iTool.Gateway;
using Core.Framework;
using HandlerContextOptions;
using Microsoft.EntityFrameworkCore;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Responses;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Ocelot.Extension
{
    public class SqlserverFileConfigurationRepository : IFileConfigurationRepository
    {
        iToolGatewayContext context = new iToolGatewayContext();

        public async Task<Response<FileConfiguration>> Get()
        {

            var fileConfiguration = new FileConfiguration
            {
                Routes = new List<FileRoute>()
            };

            var configs = await context.GatewayRoutes.ToListAsync();

            foreach (var item in configs)
            {
                if (item.RouteType == 0)
                {
                    var config = item.RouteConfig.TryToEntity<GatewayGlobalOption>();
                    fileConfiguration.GlobalConfiguration = new FileGlobalConfiguration
                    {
                        DownstreamScheme = config.DownstreamScheme,
                        LoadBalancerOptions = new FileLoadBalancerOptions
                        {
                            Type = config.LoadBalancerOptions.Type.ToString()
                        },
                        RateLimitOptions = new FileRateLimitOptions
                        {
                            HttpStatusCode = config.RateLimitOptions.HttpStatusCode,
                            DisableRateLimitHeaders = config.RateLimitOptions.DisableRateLimitHeaders,
                            QuotaExceededMessage = config.RateLimitOptions.QuotaExceededMessage,
                            ClientIdHeader = config.RateLimitOptions.ClientIdHeader
                        },
                        QoSOptions = new FileQoSOptions
                        {
                            TimeoutValue = config.QoSOptions.TimeoutValue,
                            DurationOfBreak = config.QoSOptions.DurationOfBreak,
                            ExceptionsAllowedBeforeBreaking = config.QoSOptions.ExceptionsAllowedBeforeBreaking
                        }
                    };
                }
                else
                {
                    var config = item.RouteConfig.TryToEntity<GatewayRoutesOptions>();
                    var router = new FileRoute();
                    router.UpstreamPathTemplate = config.UpstreamPathTemplate;
                    router.UpstreamHttpMethod = config.UpstreamHttpMethod.Select(item => item.ToString()).ToList();

                    router.DownstreamPathTemplate = config.DownstreamPathTemplate;
                    router.DownstreamScheme = config.DownstreamScheme;

                    var hosts = new List<FileHostAndPort>();
                    foreach (var host in config.DownstreamHostAndPorts)
                    {
                        hosts.Add(new FileHostAndPort
                        {
                            Host = host.Host,
                            Port = (int)host.Port
                        });
                    }
                    router.DownstreamHostAndPorts = hosts;

                    router.LoadBalancerOptions = new FileLoadBalancerOptions
                    {
                        Type = config.LoadBalancerOptions.Type.ToString()
                    };

                    if (config.FileCacheOptions.TtlSeconds > 0)
                    {
                        router.FileCacheOptions = new Configuration.File.FileCacheOptions
                        {
                            TtlSeconds = (int)config.FileCacheOptions.TtlSeconds
                        };
                    }

                    if (config.RateLimitOptions.EnableRateLimiting)
                    {
                        router.RateLimitOptions = new FileRateLimitRule
                        {
                            PeriodTimespan = (double)config.RateLimitOptions.PeriodTimespan,
                            Limit = (long)config.RateLimitOptions.Limit,
                            EnableRateLimiting = config.RateLimitOptions.EnableRateLimiting,
                            Period = config.RateLimitOptions.Period
                        };
                    }

                    fileConfiguration.Routes.Add(router);
                }
            }

            return new OkResponse<FileConfiguration>(fileConfiguration);
        }

        public Task<Response> Set(FileConfiguration fileConfiguration)
        {
            // save fileConfiguration
            return Task.FromResult<Response>(new OkResponse());
        }
    }
}
